package yxy.cherry.battle.module.affix;

import yxy.apple.util.RandomStringUtility;
import yxy.cherry.battle.Battle;
import yxy.cherry.battle.Fighter;
import yxy.cherry.battle.module.TriggerPoint;
import yxy.cherry.battle.module.record.stream.RecordStream;
import yxy.cherry.battle.module.selector.TargetSelector;
import yxy.cherry.battle.module.selector.TargetSelectorFactory;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.buffdate;
import yxy.cherry.data.bean.skill;

import java.util.Collection;

public abstract class Buff extends Affix {
	String buffCode;
	Fighter source; // 效果施放者
	Fighter target; // 效果作用者
	String buffCodeSeq;//存放在map中的key
	int roundCountType;//轮次计算方式
	TargetSelector targetSelector;

	int overlay;// 层数
	int overlayMax;// 层数上限 -1 无限叠加； 0 替换(更新回合数)； 1~X 叠加层数

	int round;// 有效回合数

	public Buff(Fighter source, Fighter target, skill skilldata, int[] params) {
		super(target, skilldata, params);
		buffdate _buffdate = DataCenter.getData(skilldata.getBuffid(), buffdate.class);
		if (_buffdate == null) {
			throw new NullPointerException();
		}
		this.overlayMax = skilldata.getBuffoverlay();
		this.targetSelector = TargetSelectorFactory.getInstance().getTargetSelector(skilldata.getSkillobject());//特殊的buff使用

		this.buffCode = _buffdate.getCode();
		this.source = source;
		this.target = target;
		this.buffCodeSeq = genBuffSeqCode(this.overlayMax, buffCode);
		this.round = skilldata.getBuffround();
		this.round = round <= 0 ? -1 : round;

		this.triggerPoint = TriggerPoint.valueOf(skilldata.getBufftrigger());

		this.name = _buffdate.getName();
		this.roundCountType = _buffdate.getCounttype();
	}

	/**
	 * @author James
	 * 生成用于横向叠加的BuffCode
	 * @param s_overlayMax
	 * @param s_buffCode
	 * @return
	 */
	private String genBuffSeqCode(int s_overlayMax,String s_buffCode){
		if(s_overlayMax == -1){
			return s_buffCode + "_" + RandomStringUtility.randomAlphaNumeric(8);
		}else{
			return s_buffCode + "_" + this.getSkilldata().getId();
		}
	}

	/**
	 * 为让技能能够横向、纵向、自叠增加的唯一编码
	 * @return
	 */
	public String getBuffCodeSeq() {
		return buffCodeSeq;
	}

	public String getBuffCode() {
		return buffCode;
	}

	public int getBuffId() {
		return getSkilldata().getBuffid();
	}

	public Fighter getSource() {
		return source;
	}

	public Fighter getTarget() {
		return target;
	}

	public Collection<Fighter> getBuffTargets() {return targetSelector.selectTarget(actor);}

	public boolean append(Fighter target) {
		if(overlayMax == -1){//横向叠加
			return addBuff(target);
		}else if (overlayMax == 0) {//替换操作
			return replace(target);
		} else {//纵向叠加
			return overlay(target);
		}
	}

	/**
	 * @Author James
	 * @param target 目标作用对象
	 * @return 状态
	 */
	public boolean addBuff(Fighter target){
		target.getBuffMap().put(getBuffCodeSeq(), this);
		setRecord(target.getRecord());
		return true;
	}

	/** 直接叠加 */
	public boolean overlay(Fighter target) {
		Buff buff = target.getBuffMap().get(getBuffCodeSeq());
		if (buff != null) {
			return buff.overlay();
		}
		overlay++;
		target.getBuffMap().put(getBuffCodeSeq(), this);
		setRecord(target.getRecord());
		return true;
	}

	/** 按类型替换 */
	public boolean replace(Fighter target) {
		Buff buff = target.getBuffMap().get(getBuffCodeSeq());
		if (buff != null && buff.isRunning()) {
			buff.round = this.round;
			return false;
		}
		target.getBuffMap().put(getBuffCodeSeq(), this);
		setRecord(target.getRecord());
		return true;
	}

	public boolean isRunning() {
		return round != 0;
	}

	//设置buff还运不运行，当round为0的时候则停止运行
	public void setIsRunning(int round){
		this.round = round;
	}

	//对buff轮次进行扣除，1是按照使用进行扣除，2是按照轮次进行扣除
	public static int ROUND_COUNT_TYPE_FOR_USE = 1;
	public static int ROUND_COUNT_TYPE_FOR_ROUND = 2;
	public void tick() {
		if (round <= 0) {
			return;
		}
		this.round--;
	}

	/** 覆盖操作 */
	public boolean overlay() {
		if (overlay >= overlayMax) {
			return false;
		}
		overlay++;
		this.round = skilldata.getBuffround();
		return true;
	}

	/**
	 * @author James
	 * @return 叠加层数
	 */
	public int getOverlay(){
		return overlay;
	}

	/**
	 * @author James
	 * @return 叠加层数上限
	 */
	public int getOverlayMax(){
		return overlayMax;
	}

	@Override
	public boolean active() {
		RecordStream recordStream = record();
		boolean result = this.exec(source, target);
		if (result && recordStream != null) {
			// 技能录像流
			recordStream.record();
		}
		if(roundCountType == ROUND_COUNT_TYPE_FOR_USE) {
			tick();
			Battle.battleLogger(3,"Buff回合按使用:"+this.source.getName()+"tick"+getBuffCode()+getSkilldata().getName()+"剩余回合："+getRound());
		}
		return result;
	}

	abstract public boolean exec(Fighter source, Fighter target);

	public RecordStream record() {
		return null;
	}

	public BuffType getBuffType() {
		return BuffType.无分类;
	}

	public BuffStateType getBuffStateType() {
		return BuffStateType.无状态;
	}

	static public enum BuffType {
		无分类(0), 控制效果(1), 属性减效果(2), 属性加效果(3), 减益效果(4), 增益效果(5), DOT效果(6), HOT效果(7);

		private int number;

		private BuffType(int number) {
			this.number = number;
		}

		public int getNumber() {
			return number;
		}

		static public BuffType forNumber(int value) {
			switch (value) {
			case 1:
				return 控制效果;
			case 2:
				return 属性减效果;
			case 3:
				return 属性加效果;
			case 4:
				return 减益效果;
			case 5:
				return 增益效果;
			case 6:
				return DOT效果;
			case 7:
				return HOT效果;
			default:
				return 无分类;
			}
		}

	}

	static public enum BuffStateType {
		无状态(0), //
		中毒状态(51), //
		灼烧状态(52), //
		回春状态(53), //
		眩晕状态(54), //
		麻痹状态(55), //
		沉默状态(56), //
		混乱状态(57), //
		嘲讽状态(58), //
		增伤状态(59), //
		减伤状态(60), //
		avoidKillShieldState(61), //免死盾状态
		attributeShieldState(62), //属性盾状态
		减疗状态(63), //
		属性加状态(64), //
		属性减状态(65),//
		weakState(68),//虚弱状态
		armorBreakState(69),//破甲状态
		suppressState(71),//压制状态
		collectWisdomState(72),//集智状态
		defendTenaciouslyState(73),//固守状态
		strategistState(74),//谋略状态
		sadState(75),//感伤状态
		rageState(76),//盛怒状态
		;

		private int number;

		private BuffStateType(int number) {
			this.number = number;
		}

		public int getNumber() {
			return number;
		}

		static public BuffStateType forNumber(int value) {
			switch (value) {
			case 51:
				return 中毒状态;
			case 52:
				return 灼烧状态;
			case 53:
				return 回春状态;
			case 54:
				return 眩晕状态;
			case 55:
				return 麻痹状态;
			case 56:
				return 沉默状态;
			case 57:
				return 混乱状态;
			case 58:
				return 嘲讽状态;
			case 59:
				return 增伤状态;
			case 60:
				return 减伤状态;
			case 61:
				return avoidKillShieldState;
			case 62:
				return attributeShieldState;
			case 63:
				return 减疗状态;
			case 64:
				return 属性加状态;
			case 65:
				return 属性减状态;
			case 68:
				return weakState;
			case 69:
				return armorBreakState;
			case 71:
				return suppressState;
			case 72:
				return collectWisdomState;
			case 73:
				return defendTenaciouslyState;
			case 74:
				return strategistState;
			case 75:
				return sadState;
			case 76:
				return rageState;
		default:
			return 无状态;
			}
		}

	}

	public int getRoundCountType() {
		return roundCountType;
	}

	public int getRound() {return round;}
}
